package br.senac.sp.persistence;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class RelationalDBConnector implements IRelationalDBConnector{

    private final String url;
    private final String user;
    private final String password;

    private transient ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>();

    public RelationalDBConnector(final String url, final String user, final String password) {
        this.url = url;
        this.user = user;
        this.password = password;
    }


    private Connection createConnection() {
        try {
            return  DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            throw new RuntimeException("Could not connect to database", e);
        }
    }

    @Override
    public void informTransactionCreation() {
        try {
            Connection currentConnection = getConnection();
            currentConnection.setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException("Could not start transaction", e);
        }
    }

    @Override
    public void informTransactionCommit() {
        try {
            Connection currentConnection = getConnection();
            currentConnection.commit();
            currentConnection.setAutoCommit(true);
        } catch (SQLException e) {
            throw new RuntimeException("Could not commit", e);
        }
    }

    @Override
    public void informTransactionRollback() {
        try {
            Connection currentConnection = getConnection();
            currentConnection.rollback();
            currentConnection.setAutoCommit(true);
        } catch (SQLException e) {
            throw new RuntimeException("Could not rollback", e);
        }
    }

    @Override
    public Connection getConnection() {
        Connection currentConnection = threadConnection.get();
        try {
            if(currentConnection == null || currentConnection.isClosed()) {
                currentConnection = createConnection();
                threadConnection.set(currentConnection);
            }
        } catch (SQLException e) {
            throw new RuntimeException("Could not retrieve connection state", e);
        }
        return currentConnection;
    }
}